`timescale 1ps / 1ps
module dm(input clk,
          input [1:0] MemWr,
          input [31:0] Address,
          input [31:0] DataIn,
          input [1:0] RegWr,
          output reg[31:0] DataOut);
    
    reg [31:0] DATA [1023:0];
 
/* 
	! Kilin standard
	wire [7:0] d0 = DATA[ Address[11:2] ][ 7: 0];
	wire [7:0] d1 = DATA[ Address[11:2] ][15: 8];
	wire [7:0] d2 = DATA[ Address[11:2] ][23:16];
	wire [7:0] d3 = DATA[ Address[11:2] ][31:24];
*/
	wire [7:0] d0 = DATA[Address][7:0];
    always @(*) begin
        DataOut = DATA[Address];
        //******LW******//
		if (RegWr == 2'b01)
			DataOut = DATA[Address];
        
		//*******LB********//
		if (RegWr == 2'b10) begin
			DataOut = {{24{d0[7]}},DATA[Address][7:0]};
		/*
		    ! Kilin standard
            if (Address[1:0] == 2'b00)
				DataOut = { {24{d0[7]}}, d0};
                
			if (Address[1:0] == 2'b01) 
				DataOut = { {24{d1[7]}}, d1};
			  
			if (Address[1:0] == 2'b10) 
				DataOut = { {24{d2[7]}}, d2};
			 
			if (Address[1:0] == 2'b11) 
				DataOut = { {24{d3[7]}}, d3};
		*/	
		end 

		//******LBU*******//
		if (RegWr == 2'b11) begin
			DataOut = {24'b0,d0};
		/*	
			! Kilin standard
			if (Address[1:0] == 2'b00) 
				DataOut = { 24'b0, d0};
			  
			if (Address[1:0] == 2'b01) 
				DataOut = { 24'b0, d1};
			  
			if (Address[1:0] == 2'b10) 
				DataOut = { 24'b0, d2};
			 
			if (Address[1:0] == 2'b11) 
				DataOut = { 24'b0, d3};
		*/	
		end
    end

    always @(posedge clk) begin
        if (MemWr == 1) DATA[Address] = DataIn;
        /*
		! Kilin standard
		if (MemWr == 2) begin
            if (Address[1:0] == 2'b00) DATA[ Address[11:2] ][ 7: 0] <= DataIn[7:0];else 
			if (Address[1:0] == 2'b01) DATA[ Address[11:2] ][15: 8] <= DataIn[7:0];else 
			if (Address[1:0] == 2'b10) DATA[ Address[11:2] ][23:16] <= DataIn[7:0];else 
			if (Address[1:0] == 2'b11) DATA[ Address[11:2] ][31:24] <= DataIn[7:0];
        end
		*/
		if (MemWr == 2) DATA[Address] <= DataIn[7:0];
    end
    
endmodule
